package com.cloud.drore.eboss.operation.service.impl;

import com.cloud.drore.eboos.common.base.*;


import com.cloud.drore.eboos.common.base.Dictionary;
import com.cloud.drore.eboos.common.entity.base.UserInfo;
import com.cloud.drore.eboos.common.entity.dealer.MerchantVo;

import com.cloud.drore.eboos.common.util.CodingGeneration;
import com.cloud.drore.eboos.common.util.LocalData;
import com.cloud.drore.eboos.common.util.LocalDateAndDateTransformUtil;
import com.cloud.drore.eboos.exception.BusinessException;
import com.cloud.drore.eboss.login.feign.ILoginFeign;
import com.cloud.drore.eboss.operation.entity.DistributorAccount;
import com.cloud.drore.eboss.operation.entity.Merchant;
import com.cloud.drore.eboss.operation.entity.MerchantMulti;
import com.cloud.drore.eboss.operation.entity.MerchantRedisAccount;
import com.cloud.drore.eboss.operation.entity.po.MerchantPo;
import com.cloud.drore.eboss.operation.entity.vo.DictionaryMerchantVo;
import com.cloud.drore.eboss.operation.entity.vo.DistributorForRedisInfoVo;
import com.cloud.drore.eboss.operation.entity.vo.MerchantManageVo;
import com.cloud.drore.eboss.operation.mapper.*;
import com.cloud.drore.eboss.operation.service.IBaseDataFeign;
import com.cloud.drore.eboss.operation.service.IMerchantService;
import com.cloud.drore.eboss.operation.supplierApiService.IMerchantSupplierApiService;
import com.cloud.drore.eboss.util.DictionaryMapUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.cloud.drore.eboos.common.constant.RedisConstant.OTA_CASH_POOL;
import static com.cloud.drore.eboos.common.constant.RedisConstant.TRAVEL_CASH_POOL;


/**
 * 浙江卓锐科技股份有限公司 版权所有  Copyright 2018<br>
 *
 * @Description: <br>
 * @Project: eboos <br>
 * @CreateDate: Created in 2018/1/6 0006 下午 1:08 <br>
 * @Author: <a href="410508961@qq.com">夏凯</a>
 */
@Service
@Slf4j
public class MerchantServiceImpl extends BaseServiceImpl implements IMerchantService, IMerchantSupplierApiService {
    @Autowired
    MerchantMapper merchantMapper;
    @Autowired
    IBaseDataFeign iBaseDataFeign;
    @Autowired
    MerchantMultiMapper merchantMultiMapper;
    @Autowired
    DistributorAccountServiceImpl distributorAccountServiceImpl;
    @Autowired
    MerchantManageMapper merchantManageMapper;
    @Autowired
    ILoginFeign iLoginFeign;
    @Resource
    ConsumeMapper consumeMapper;
    @Resource
    FinaceSettlementHistoryServiceImpl finaceSettlementHistoryServiceImpl;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //private RedisTemplate<String, String> stringRedisTemplate;
    @Resource
    POIMapper POIMapper;
    @Resource
    DistributorMapper distributorMapper;

    @Override
    public MyMapper getMapper() {
        return merchantMapper;
    }

    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return:
     * @Decription: 初始化查询商户列表o
     * @CreateDate: Created in 2018/1/6 0006 下午 1:19
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public ResultMessage findByName() {

        DictionaryMerchantVo dictionaryMerchantVo = new DictionaryMerchantVo();
        //查询字典得到商户类型
        dictionaryMerchantVo.setDictionaryGoodsSaleType(iBaseDataFeign.getDicListMapByCodeVo("GOODS_SALE_TYPE"));
        //查询字典得到商户类型
        dictionaryMerchantVo.setDictionaryMerchantType(iBaseDataFeign.getDicListMapByCodeVo("MERCHANT_TYPE"));
        //商户行业
        dictionaryMerchantVo.setDictionaryMerchantIndustry(iBaseDataFeign.getDicListMapByCodeVo("MERCHANT_INDUSTRY"));
        //查询字典得到商户性质
        dictionaryMerchantVo.setDictionaryMerchantCharacter(iBaseDataFeign.getDicListMapByCodeVo("MERCHANT_CHARACTER"));
        //查询字典得到商户管理员类型信息
        dictionaryMerchantVo.setDictionaryMerchantManager(iBaseDataFeign.getDicListMapByCodeVo("USE_ROLE"));
        //经营性质
        dictionaryMerchantVo.setDictionaryBusinessNature(iBaseDataFeign.getDicListMapByCodeVo("BUSINESS_NATURE"));
        return new ResultMessage(dictionaryMerchantVo);
    }


    /**
     * @param merchant
     * @ClassName: MerchantServiceImpl
     * @Return: com.cloud.drore.eboos.common.base.ResultMessage<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 更新审核通过的商户信息
     * @CreateDate: Created in 2018/1/9 0009 下午 5:45
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public int update(Merchant merchant) {
        //修改商户销售产品以外的本信息
        return merchantMapper.updateMerchantStateSql(merchant);
    }

    /**
     * @param goodsSaleTypeListTotal
     * @param merchant
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboos.common.base.Dictionary>
     * @Decription: 过滤复选框上传的信息
     * @CreateDate: Created in 2018/1/17 0017 下午 7:04
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<Dictionary> MerchantMuitiFilter(List<Dictionary> goodsSaleTypeListTotal, Merchant merchant) {
        List<Dictionary> collect = goodsSaleTypeListTotal.stream().filter(dictionary ->
                !merchant.getGoodsSaleType().toString()
                        .contains(dictionary.getDicCode())
        ).collect(Collectors.toList());
        return collect;
    }

    /**
     * @param key
     * @ClassName: MerchantServiceImpl
     * @Return: int
     * @Decription: 商户作废：poi进行下架，消费点进行下架
     * @CreateDate: Created in 2018/1/10 0010 下午 2:42
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    @Transactional
    public int delete(Object key) {
        //查询得到商户的类型
        Merchant merchant = merchantMapper.selectByPrimaryKey(key);
        if (merchant.getMerchantType().equals("MERCHANT_SUPPLIER")) {
            //根据商户id，poi进行下架
            POIMapper.deletePoiList(key);
            //根据商户id，消费点进行下架
            consumeMapper.updateConsumeState(key);
        }
        if (merchant.getMerchantType().equals("MERCHANT_DISTRIBUTE")) {
            //分销商账户进行下架
            distributorMapper.updateDistributorAccoutState(Long.parseLong(key.toString()));
        }
        //需要改变产品的上架状态
        return merchantMapper.deleteMerchantSql(key);
    }

    /**
     * @param key
     * @ClassName: MerchantServiceImpl
     * @Return: int
     * @Decription: 恢复商户信息
     * @CreateDate: Created in 2018/1/10 0010 下午 2:42
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public int back(Object key) {
        return merchantMapper.backMerchantSql(key);
    }

    /**
     * @param merchant
     * @ClassName: MerchantServiceImpl
     * @Return: void
     * @Decription: 如果是分销商需要添加分销商账户的信息
     * @CreateDate: Created in 2018/1/17 0017 上午 9:49
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public void insertDistributor(Merchant merchant) {
        DistributorAccount distributorAccount = new DistributorAccount();
        distributorAccount.setAccountBalance(new BigDecimal(0));
        distributorAccount.setAccountMinBalance(new BigDecimal(5000));
        distributorAccount.setDistributorId(merchant.getId());
        distributorAccount.setDistributorName(merchant.getMerchantName());
        distributorAccount.setDistributorIndustry(merchant.getMerchantIndustry());
        distributorAccount.setMerchantNum(merchant.getMerchantNum());
        distributorAccountServiceImpl.insert(distributorAccount);
    }

    /**
     * @param merchant
     * @ClassName: MerchantServiceImpl
     * @Return: com.cloud.drore.eboss.operation.entity.Merchant
     * @Decription: 商户页面数据的插入字典查询，同时分销增加分销商的账户信息
     * @CreateDate: Created in 2018/1/11 0011 上午 10:46
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    @Transactional
    public Merchant selectDictory(Merchant merchant) {
        //判断商户名称是否能重复
        List<Merchant> merchantList = merchantMapper.findMerchantList(merchant.getMerchantName());
        if (merchantList.size() >= 1) {
            throw new RuntimeException("商户名称不能重复");
        }
        //插入商户信息
        merchant.setMerchantState("MERCHANT_AUDIT_ALREADY");
        insert(merchant);

        //给商户添加商户编号
        String merchantGenerationCodingNum = CodingGeneration.getMerchantGenerationCodingNum(merchant.getMerchantType(), merchant.getId());
        merchantMapper.updateMerchantNum(merchant.getId(), merchantGenerationCodingNum);
        //拿到前端的多选数据类型
        List<String> multiList = merchant.getGoodsSaleType();
        //批量插入多选框的状态
        List list = new ArrayList();
        UserInfo currentUser = LocalData.getCurrentUser();
        Date date = new Date();
        if (!("".equals(multiList) || null == multiList)) {
            multiList.stream().forEach(multis -> {
                MerchantMulti merchantMulti = new MerchantMulti();
                //商户id
                merchantMulti.setMerchantId(merchant.getId());
                //dicCode
                merchantMulti.setDicCode(multis);
                //给数据信息赋予拥有状态
                merchantMulti.setState("0");
                merchantMulti.setCreatedDate(date);
                merchantMulti.setCreatedBy(currentUser.getId().toString());
                list.add(merchantMulti);
            });
        }
        List<Dictionary> goodsSaleTypeList = iBaseDataFeign.getDicListMapByCode("GOODS_SALE_TYPE");
        //过滤复选框上传的信息
        //List<Dictionary> collect = MerchantMuitiFilter(goodsSaleTypeList, merchant);
        List<Dictionary> collect = goodsSaleTypeList.stream().filter(dictionary ->
                !merchant.getGoodsSaleType().toString()
                        .contains(dictionary.getDicCode())
        ).collect(Collectors.toList());
        //批量插入关联表相关信息,非拥有状态state是1
        if (collect.size() > 0) {
            collect.stream().forEach(dictionary -> {
                MerchantMulti merchantCollect = new MerchantMulti();
                //商户id
                merchantCollect.setMerchantId(merchant.getId());
                //dicCode
                merchantCollect.setDicCode(dictionary.getDicCode());
                //给数据信息赋予拥有状态
                merchantCollect.setState("1");
                merchantCollect.setCreatedDate(date);
                merchantCollect.setCreatedBy(currentUser.getId().toString());
                list.add(merchantCollect);
            });
        }
        //多选框批量数据插入
        merchantMultiMapper.insertList((List<MerchantMulti>) list);

        //添加分销商账户的信息
        if ("MERCHANT_DISTRIBUTE".equals(merchant.getMerchantType())) {
            //如果是分销商，需要添加分销商账户的信息
            merchant.setMerchantNum(merchantGenerationCodingNum);
            insertDistributor(merchant);
            //如果是分销商，需要给redis添加账户的资金池
            setDistributorCashInfo(merchant);
        }
        return merchant;
    }

    /**
     * @param merchant
     * @ClassName: MerchantServiceImpl
     * @Return: void
     * @Decription: 设定资金池账户信息
     * @CreateDate: Created in 2018/3/23 0023 下午 6:04
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public void setDistributorCashInfo(Merchant merchant) {
        //判断旅行社还是ota
        String key;
        switch (merchant.getMerchantIndustry()) {
            // OTA
            case "MERCHANT_INDUSTRY_OTA":
                key = merchant.getMerchantNum() + OTA_CASH_POOL;
                break;
            // 旅行社
            case "MERCHANT_INDUSTRY_HOUSEKEEPER":
                key = merchant.getMerchantNum() + TRAVEL_CASH_POOL;
                break;
            default:
                throw new RuntimeException("redis的key值获取失败！");
        }
        stringRedisTemplate.opsForValue().set(key, "0");
    }

    /**
     * @param page
     * @ClassName: MerchantServiceImpl
     * @Return: com.cloud.drore.eboos.common.base.ResultMessage
     * @Decription: 商户根据筛选条件进行查询
     * @CreateDate: Created in 2018/1/12 0012 上午 11:57
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public ResultMessage findByData(PagePo page) {

        MerchantPo merchant = (MerchantPo) page.getFields();
        // 设置商户查找的属性
        Example merchantExample = new Example(Merchant.class);
        Example.Criteria criteria = merchantExample.createCriteria();

        //商户名称
        if (StringUtils.isNotEmpty(merchant.getMerchantName())) {
            //  criteria.andLike("merchantName", merchant.getMerchantName());
            criteria.andLike("merchantName", "%" + merchant.getMerchantName() + "%");
        }
        //商户类型
        if (StringUtils.isNotEmpty(merchant.getMerchantType())) {
            criteria.andEqualTo("merchantType", merchant.getMerchantType());
        }
        merchantExample.setOrderByClause("id desc");
        PageHelper.startPage(page);
        //根据实际条件进行字段的查询
        List<Merchant> merchantList = merchantMapper.selectByExample(merchantExample);

        //  List<MerchantOperationVo> merchantList= merchantMapper.queryMerchantInitList(merchant);
        long total = new PageInfo(merchantList).getTotal();
        //得到管理员的列表map
        Map<String, String> merchantManageMapById = getMerchantManageMapById();
        //商户审核状态
        Map<String, String> merchantManageStateMap = DictionaryMapUtil.getMapByParentCode("MERCHANT_AUDIT_STATE");
        //把商户的状态进行翻译
        merchantList = merchantList.stream().map(merchantForCodeToName -> {
            merchantForCodeToName.setMerchantStateCodeToName(merchantManageStateMap.get(merchantForCodeToName.getMerchantState()));
            Long merchantManager = merchantForCodeToName.getMerchantManager();
            if (!(null == merchantManager || "".equals(merchantManager))) {
                merchantForCodeToName.setMerchantManageName(merchantManageMapById.get(merchantManager.toString()));
            }
            return merchantForCodeToName;
        }).collect(Collectors.toList());
        PageInfo pageInfo = new PageInfo<>(merchantList);
        log.info(merchantList.toString());
        pageInfo.setTotal(total);
        return ResultMessage.success(pageInfo);

    }

    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.Map
     * @Decription: 根据商户管理员ID得到管理员名称的map 管理员之门
     * @CreateDate: Created in 2018/3/5 0005 下午 2:57
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public Map<String, String> getMerchantManageMapById() {
        Map<String, String> merchantHashMap = new HashMap<>();
        //iLoginFeign.findUserList();
        List<MerchantManageVo> merchantManageVoList = merchantManageMapper.merchantManageVos();
        for (MerchantManageVo merchantManageVo : merchantManageVoList) {
            merchantHashMap.put(merchantManageVo.getId().toString(), merchantManageVo.getAccountName());
        }
        return merchantHashMap;
    }

    /**
     * @param merchantMultiList
     * @param merchantList
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 两个list重复的id对象保留
     * @CreateDate: Created in 2018/1/12 0012 上午 11:56
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */

    public List<Merchant> removeMerchantList(List<MerchantMulti> merchantMultiList,
                                             List<Merchant> merchantList) {
        //外围的是需要过滤的条件
        List<Merchant> collect = merchantList.stream().filter(merchant ->
                merchantMultiList.stream().map(MerchantMulti::getMerchantId)
                        .collect(Collectors.toList())
                        .contains(merchant.getId())
        ).collect(Collectors.toList());
        return collect;
    }

    /**
     * @param id
     * @ClassName: MerchantServiceImpl
     * @Return: com.cloud.drore.eboss.operation.entity.Merchant
     * @Decription: 查询单个商户接口内容
     * @CreateDate: Created in 2018/1/18 0018 下午 7:52
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    @Transactional
    public Merchant getMerchant(Long id) {

        Merchant merchant = merchantMapper.selectByPrimaryKey(id);
        merchant.setMerchantType(iBaseDataFeign.getDictionary(merchant.getMerchantType()).getName());
        merchant.setMerchantCharacter(iBaseDataFeign.getDictionary(merchant.getMerchantCharacter()).getName());
        merchant.setMerchantIndustry(iBaseDataFeign.getDictionary(merchant.getMerchantIndustry()).getName());
        merchant.setMerchantState(iBaseDataFeign.getDictionary(merchant.getMerchantState()).getName());
        //查询需要显示的复选框信息
        List<MerchantMulti> merchantMultiList = merchantMultiMapper.selectMerchantMultiList(merchant.getId());
        //销售产品类型的map
        Map<String, String> goodsSaleTypeMap = DictionaryMapUtil.getMapByParentCode("GOODS_SALE_TYPE");
        List<String> goodsSaleType = merchantMultiList.stream().map(merchantMultiForCodeToName -> {
            merchantMultiForCodeToName.setName(goodsSaleTypeMap.get(merchantMultiForCodeToName.getDicCode()));
            return merchantMultiForCodeToName;
        }).map(MerchantMulti::getName).collect(Collectors.toList());
        merchant.setGoodsSaleType(goodsSaleType);
        return merchant;
    }

    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 提供给供应商使用的接口，查询所有供应商商户列表
     * @CreateDate: Created in 2018/1/23 0023 下午 3:00
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<Merchant> selectMerchantList() {
        return merchantMapper.query();
    }


    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 提供给供应商使用的接口，查询所有供应商商户列表
     * @CreateDate: Created in 2018/1/23 0023 下午 3:00
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<MerchantVo> getSupplierListDictionary() {
        return merchantMapper.getSupplierListDictionary();
    }

    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 提供给供应商使用的接口，查询所有分销商商户列表
     * @CreateDate: Created in 2018/1/23 0023 下午 3:00
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<MerchantVo> getDealerListDictionary() {
        return merchantMapper.getDealerListDictionary();
    }

    /**
     * @param
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.Merchant>
     * @Decription: 提供给分销商商使用的接口，查询所有分销商商户列表
     * @CreateDate: Created in 2018/1/31 0031 下午 6:19
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<Merchant> selectMerchantListDistributor() {

        return merchantMapper.queryDistributor();
    }

    /**
     * @param id
     * @ClassName: MerchantServiceImpl
     * @Return: java.util.List<com.cloud.drore.eboss.operation.entity.MerchantMulti>
     * @Decription: 通过供应商的id查询复选框的信息
     * @CreateDate: Created in 2018/3/7 0007 上午 10:17
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public List<String> queryMerchantGoodsSaleType(Long id) {
        List<MerchantMulti> merchantMultiList = merchantMultiMapper.selectMerchantMultiList(id);
        List<String> merchantMultiInfo = merchantMultiList.stream().map(merchantMulti -> merchantMulti.getDicCode()
        ).collect(Collectors.toList());
        return merchantMultiInfo;
    }

    /**
     * @param merchantRedisAccount
     * @ClassName: MerchantServiceImpl
     * @Return: java.math.BigDecimal
     * @Decription: 根据商户名称查询对应的现金池
     * @CreateDate: Created in 2018/4/8 0008 下午 4:48
     * @Author: <a href="410508961@qq.com">夏凯</a>
     * @Modify:
     */
    public BigDecimal queryMerchantCool(MerchantRedisAccount merchantRedisAccount) {
        //根据商户名称获得merchant_num、merchant_industry
        Merchant merchant = merchantMapper.queryMerchantByName(merchantRedisAccount.getMerchantName());
        DistributorForRedisInfoVo distributorForRedisInfoVo = new DistributorForRedisInfoVo();
        distributorForRedisInfoVo.setMerchantNum(merchant.getMerchantNum());
        distributorForRedisInfoVo.setMerchantIndustry(merchant.getMerchantIndustry());
        String key = finaceSettlementHistoryServiceImpl.judgeOtaOrHousekeeper(distributorForRedisInfoVo);
        BigDecimal bigDecimal = new BigDecimal(stringRedisTemplate.opsForValue().get(key).toString());
        return bigDecimal;
    }
}